﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 低频天线阵列相控阵信号发生系统SmartFASK12.Controls
{
    public class MJietiao5
    {
        private static MJietiao5 _instance = null;
        private Random _rand = new Random();
        private MJietiao5()
        {

        }

        public static MJietiao5 Singleton()
        {
            if (_instance == null)
            {
                _instance = new MJietiao5();
            }

            return _instance;
        }

        public MJietiaoShowResultFSK JietiaoFSK(List<double> yvalues, int samplefre, int fre1, int bandwidth1, int order1, int fre2, int bandwidth2, int order2, int shift, int signalFre, bool isGuiyi, bool isAutoFirst, int autoValue = 0)
        {
            MJietiaoShowResultFSK res = new MJietiaoShowResultFSK();

            res.YValues = yvalues;

            try
            {
                #region 根据采样率生成x数据
                List<double> xvalues = new List<double>();
                double interval = 1.0 / samplefre;
                double cx = 0;
                for (int i = 0; i < yvalues.Count; i++)
                {
                    xvalues.Add(cx);

                    cx += interval;
                }
                #endregion

                #region 初始化数据
                MData pdata = new MData();
                pdata.XValues = xvalues;
                pdata.YValues = yvalues;

                res.Times = xvalues;
                for (int i = 0; i < xvalues.Count; i++)
                {
                    res.Judge_X.Add(i);
                }
                #endregion

                #region 频率1处理
                if (true)
                {
                    MData dd = MyMatlab2.Filter(pdata, fre1, bandwidth1, samplefre, order1);

                    MData fftdd = MyMatlab2.FFT(dd.YValues, samplefre);

                    MData hil = MyMatlab2.Hilbert(dd);

                    pdata.DataFre1 = hil.YValues;

                    res.Orig_Y1 = dd.YValues;
                    res.FFT_X1 = fftdd.XValues;
                    res.FFT_Y1 = fftdd.YValues;
                    res.Bao_Y1 = hil.YValues;
                }
                #endregion

                #region 频率2处理
                if (true)
                {
                    MData dd = MyMatlab2.Filter(pdata, fre2, bandwidth2, samplefre, order2);

                    MData fftdd = MyMatlab2.FFT(dd.YValues, samplefre);

                    MData hil = MyMatlab2.Hilbert(dd);

                    pdata.DataFre2 = hil.YValues;

                    res.Orig_Y2 = dd.YValues;
                    res.FFT_X2 = fftdd.XValues;
                    res.FFT_Y2 = fftdd.YValues;
                    res.Bao_Y2 = hil.YValues;
                }
                #endregion

                #region 解调
                if (pdata.HasDataFre())
                {
                    int disnum = samplefre / signalFre;

                    pdata.Judgement(shift, disnum, isGuiyi, ref res);

                    res.AutoFirst(isAutoFirst, autoValue);
                }
                #endregion

            }
            catch
            {
                return null;
            }




            return res;
        }

        public MJietiaoShowResultFSK JietiaoFSK2(List<double> orgYvaluess, int samplefre, int fre1, int bandwidth1, int order1, int fre2, int bandwidth2, int order2, int shift, int signalFre, bool isGuiyi, bool isAutoFirst, int autovalue, double midValue, double checkValue)
        {
            MJietiaoShowResultFSK res = new MJietiaoShowResultFSK();

            try
            {
                #region 找到有效的数据段
                List<double> effyvalues = new List<double>();

                int checkCntStart = (int)(samplefre * 0.12 / fre2);
                if (checkCntStart < 2)
                {
                    checkCntStart = 2;
                }

                int checkCntEnd = samplefre / fre2;
                double maxCheck = midValue + checkValue;
                double minCheck = midValue - checkValue;

                bool isFindStart = false;
                for (int i = 0; i < orgYvaluess.Count; i++)
                {
                    if (!isFindStart)
                    {
                        bool isOk = true;
                        for (int k = 0; k < checkCntStart; k++)
                        {
                            if (orgYvaluess[i + k] < maxCheck && orgYvaluess[i + k] > minCheck)
                            {
                                isOk = false;
                                break;
                            }
                        }

                        if (isOk)
                        {
                            isFindStart = true;

                            effyvalues.Add(orgYvaluess[i]);
                        }
                    }
                    else
                    {
                        bool isEnd = true;
                        for (int k = 0; k < checkCntEnd; k++)
                        {
                            if (orgYvaluess[i + k] >= maxCheck || orgYvaluess[i + k] <= minCheck)
                            {
                                isEnd = false;
                                break;
                            }
                        }

                        if (!isEnd)
                        {
                            effyvalues.Add(orgYvaluess[i]);
                        }
                        else
                        {
                            break;
                        }

                    }
                }

                #endregion

                res = JietiaoFSK(effyvalues, samplefre, fre1, bandwidth1, order1, fre2, bandwidth2, order2, shift, signalFre, isGuiyi, isAutoFirst, autovalue);

            }
            catch
            {
                return null;
            }




            return res;
        }

        /// <summary>
        /// 解调ASK
        /// </summary>
        /// <param name="yvalues"></param>
        /// <param name="samplefre"></param>
        /// <param name="fre1"></param>
        /// <param name="bandwidth1"></param>
        /// <param name="order1"></param>
        /// <param name="shift"></param>
        /// <param name="signalFre"></param>
        /// <param name="showcnt"></param>
        /// <param name="num"></param>
        /// <param name="mid"></param>
        /// <param name="amp"></param>
        /// <returns></returns>
        public MJietiaoShowResultFSK2 JietiaoASK(List<double> yvalues, int samplefre, int fre1, int bandwidth1, int order1, int shift, int signalFre, int showcnt, int num = 10, double mid = 0, double amp = 0.05)
        {
            MJietiaoShowResultFSK2 res = new MJietiaoShowResultFSK2();

            res.YValues = yvalues;

            try
            {
                #region 根据采样率生成x数据
                List<double> xvalues = new List<double>();
                double interval = 1.0 / samplefre;
                double cx = 0;
                for (int i = 0; i < yvalues.Count; i++)
                {
                    xvalues.Add(cx);

                    cx += interval;
                }
                #endregion

                #region 初始化数据
                MData pdata = new MData();
                pdata.XValues = xvalues;
                pdata.YValues = yvalues;

                // 过滤数据
                pdata.CutZero(num, mid, amp);

                res.Times = xvalues;
                for (int i = 0; i < xvalues.Count; i++)
                {
                    res.Judge_X.Add(i);
                }
                #endregion

                #region 频率1处理
                if (true)
                {
                    MData dd = MyMatlab2.Filter(pdata, fre1, bandwidth1, samplefre, order1);

                    MData fftdd = MyMatlab2.FFT(dd.YValues, samplefre);

                    MData hil = MyMatlab2.Hilbert(dd);

                    pdata.DataFre1 = hil.YValues;

                    res.Orig_Y1 = dd.YValues;
                    res.FFT_X1 = fftdd.XValues;
                    res.FFT_Y1 = fftdd.YValues;
                    res.Bao_Y1 = hil.YValues;
                }
                #endregion

                #region 解调
                if (pdata.DataFre1.Count > 0)
                {
                    int disnum = samplefre / signalFre;

                    pdata.JudgementASK(shift, disnum, showcnt);

                    res.JudgePoints = pdata.JudgePoints;
                    res.JudgeResult = pdata.JudgeResult;
                    res.FinalResult = pdata.FinalResult;
                    res.JudgeShowPointsFull = pdata.JudgeShowPointsFull;
                    res.JudgeShowPointsPart = pdata.JudgeShowPointsPart;

                }
                #endregion

            }
            catch
            {
                return null;
            }




            return res;
        }


        /// <summary>
        /// 生成一秒的数据
        /// </summary>
        /// <param name="signalFre">信号频率</param>
        /// <param name="sampleFre">采样率</param>
        /// <param name="fre1">频率1,低频</param>
        /// <param name="amp1">频率1幅度</param>
        /// <param name="offset1">频率1基准</param>
        /// <param name="fre2">频率2,高频</param>
        /// <param name="amp2">频率2幅度</param>
        /// <param name="offset2">频率2基准</param>
        /// <param name="signalType">信号类型，1=010101...,2=随机</param>
        /// <returns></returns>
        public List<double> CalSingal(int signalFre, int sampleFre, int fre1, double amp1, double offset1, int fre2, double amp2, double offset2, int signalType)
        {
            List<double> res = new List<double>();

            List<int> numberSignal = new List<int>();
            if (true)
            {
                int n0 = sampleFre / signalFre;
                int lastIndex = -1;
                int currentValue = 0;
                for (int i = 0; i < sampleFre; i++)
                {
                    int cindex = i / n0;
                    if (cindex != lastIndex)
                    {
                        lastIndex = cindex;

                        currentValue = cindex % 2;

                        if (signalType == 2)
                        {
                            currentValue = _rand.Next(0, 100) % 2;
                        }
                    }

                    numberSignal.Add(currentValue);
                }

            }



            List<double> data1 = new List<double>();
            List<double> data2 = new List<double>();
            if (true)
            {
                for (int i = 0; i < sampleFre; i++)
                {
                    double cv1 = offset1 + amp1 * Math.Sin(Math.PI * 2.0 * i * fre1 / sampleFre);

                    double cv2 = offset2 + amp2 * Math.Sin(Math.PI * 2.0 * i * fre2 / sampleFre);

                    data1.Add(cv1);
                    data2.Add(cv2);

                }
            }

            for (int i = 0; i < sampleFre; i++)
            {
                if (numberSignal[i] == 0)
                {
                    res.Add(data1[i]);
                }
                else
                {
                    res.Add(data2[i]);
                }
            }


            return res;
        }
    }

    public class MJietiaoShowResultFSK2
    {

        public List<double> Times = new List<double>();   //横坐标时间轴数据，如果没有X，就用这个

        public List<double> YValues = new List<double>(); //有效数据Y

        public List<double> Orig_Y1 = new List<double>(); //频率1 滤波后原始数据Y
        public List<double> FFT_X1 = new List<double>();  //频率1 FFT的x坐标
        public List<double> FFT_Y1 = new List<double>();  //频率1 FFT的y坐标
        public List<double> Bao_Y1 = new List<double>();  //频率1 包络数据Y

        public List<double> Orig_Y2 = new List<double>(); //频率2 滤波后原始数据Y
        public List<double> FFT_X2 = new List<double>();  //频率2 FFT的x坐标
        public List<double> FFT_Y2 = new List<double>();  //频率2 FFT的y坐标
        public List<double> Bao_Y2 = new List<double>();  //频率2 包络数据Y

        public List<int> Judge_X = new List<int>();    //判别后横坐标为个数的
        public List<int> Judge_Y = new List<int>();    //判别后纵坐标

        public List<int> ChouYang_X = new List<int>();  //抽样点的X
        public List<int> ChouYang_Y = new List<int>();  //抽样点的Y

        public List<int> JudgeResult = new List<int>(); //判别后的序列，不用显示

        public MResultInfo ResultInfo = new MResultInfo(); //解调结果

        public List<int> FinalResult = new List<int>();
        public List<int[]> JudgeShowPointsPart = new List<int[]>();
        public List<int[]> JudgeShowPointsFull = new List<int[]>();
        public Dictionary<int, int> JudgePoints = new Dictionary<int, int>();

        private void UpdateResultInfo()
        {
            ResultInfo.JudgeResult = JudgeResult;
        }

        public void AutoFirst(bool isAuotFisrt, int autovalue = 0)
        {
            if (isAuotFisrt)
            {
                JudgeResult.Insert(0, autovalue);

                //if (JudgeResult.Count>0)
                //{
                //    if(JudgeResult[0]==0)
                //    {

                //    }
                //    else
                //    {
                //        JudgeResult.Insert(0, 0);
                //    }
                //}
            }

            UpdateResultInfo();
        }

        /// <summary>
        /// 总数
        /// </summary>
        public int TotalCount
        {
            get { return FinalResult.Count; }
        }

        /// <summary>
        /// 1的个数
        /// </summary>
        public int OneCount
        {
            get { return FinalResult.Sum(); }
        }

        /// <summary>
        /// 0的个数
        /// </summary>
        public int ZeroCount
        {
            get { return TotalCount - OneCount; }
        }

        /// <summary>
        /// 获取结果序列字符串
        /// </summary>
        /// <returns></returns>
        public string GetStringASK()
        {
            string res = string.Format("总数：{0}，1个数：{1}，0个数：{2}\r\n", TotalCount, OneCount, ZeroCount);

            for (int i = 0; i < FinalResult.Count; i++)
            {
                res += FinalResult[i].ToString();
            }

            return res;
        }
    }

    public class MResultInfo2
    {
        public List<int> JudgeResult = new List<int>();

        /// <summary>
        /// 总数
        /// </summary>
        public int TotalCount
        {
            get { return JudgeResult.Count; }
        }

        /// <summary>
        /// 1的个数
        /// </summary>
        public int OneCount
        {
            get { return JudgeResult.Sum(); }
        }

        /// <summary>
        /// 0的个数
        /// </summary>
        public int ZeroCount
        {
            get { return TotalCount - OneCount; }
        }

        /// <summary>
        /// 获取结果序列字符串
        /// </summary>
        /// <returns></returns>
        public string GetString()
        {
            string res = "";

            for (int i = 0; i < JudgeResult.Count; i++)
            {
                res += JudgeResult[i].ToString();
            }

            return res;
        }

        /// <summary>
        /// 获取结果序列字符串
        /// </summary>
        /// <returns></returns>
        public string GetString(double rate)
        {
            string res = string.Format("总数：{0}，1个数：{1}，0个数：{2}，误码率：{3}%\r\n", TotalCount, OneCount, ZeroCount, rate);

            for (int i = 0; i < JudgeResult.Count; i++)
            {
                res += JudgeResult[i].ToString();
            }

            return res;
        }
    }
}
